package com.trippin.server;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public enum AttractionTypeCluster {

	SHOPPING, SIGHTSEEING, HARD, EXTREME, LAID_BACK, PLAY, LEISURE;

	
	private static Map<AttractionTypeCluster, List<AttractionType> > clustersTypes = new HashMap<AttractionTypeCluster, List<AttractionType>>();
	static {
		Set<AttractionTypeCluster> allClusters = EnumSet.allOf(AttractionTypeCluster.class);
		for (AttractionTypeCluster cluster : allClusters) {
			List<AttractionType> clusterTypes = new ArrayList<AttractionType>();
			switch(cluster) {
			case SHOPPING:
				clusterTypes.add(AttractionType.FARE);
				break;
			case SIGHTSEEING:
				clusterTypes.add(AttractionType.SIGHTSEEING);
				clusterTypes.add(AttractionType.PILGRIMAGE_RELIGIOUS);
				break;
			case HARD:
				clusterTypes.add(AttractionType.EXTREME_ACTIVITY);
				clusterTypes.add(AttractionType.HIKE);
				break;
			case EXTREME:
				clusterTypes.add(AttractionType.EXTREME_ACTIVITY);
				break;
			case LAID_BACK:
				clusterTypes.add(AttractionType.RELAXATIONS);
				clusterTypes.add(AttractionType.CRUISE);
				break;
			case PLAY:
				clusterTypes.add(AttractionType.AMUSEMNET_PARK);
				break;
			case LEISURE:
				clusterTypes.add(AttractionType.CONCERT);
				clusterTypes.add(AttractionType.FARE);
				clusterTypes.add(AttractionType.CRUISE);
				break;
			}
			clustersTypes.put(cluster, clusterTypes);
		}
	}


	public static List<AttractionTypeCluster> getOrderedAttractionTypeCluster(Iterable<AttractionType> attrsTypes) {

		Map<AttractionTypeCluster, Integer> clusterMap = new HashMap<AttractionTypeCluster, Integer>();

		for(AttractionType type : attrsTypes) {
			List<AttractionTypeCluster> typeClusters = AttractionTypeCluster.getTypeClusters(type);
			if(typeClusters != null) {
				for(AttractionTypeCluster typeCluster : typeClusters) {			
					Integer val = clusterMap.get(typeCluster);
					if(val == null) {
						val = 0;
					}
					clusterMap.put(typeCluster, val + 1);
				}
			}
		}

		TreeMap<AttractionTypeCluster, Integer> orderedclusterMap = new TreeMap<AttractionTypeCluster, Integer>(
				new MapValueComparator(clusterMap));

		return new ArrayList<AttractionTypeCluster>(orderedclusterMap.keySet());
	}
	
	public boolean isTypeInCluster(AttractionType type) {
		return clustersTypes.get(this).contains(type);
		
	}

	public static List<AttractionTypeCluster> getTypeClusters(AttractionType type) {
		List<AttractionTypeCluster> typeClusters = new ArrayList<AttractionTypeCluster>();
		
		for(AttractionTypeCluster cluster : clustersTypes.keySet()) {
			if(clustersTypes.get(cluster).contains(type)) {
				typeClusters.add(cluster);
			}
		}
		return typeClusters;
	}



	private static class MapValueComparator implements Comparator<AttractionTypeCluster> {

		private Map<AttractionTypeCluster, Integer> base;

		public MapValueComparator(Map<AttractionTypeCluster, Integer> base) {
			this.base = base;
		}

		@Override
		public int compare(AttractionTypeCluster o1, AttractionTypeCluster o2) {

			if(base.get(o1) < base.get(o2)) {
				return 1;
			} else {
				return -1;
			}
		}
	}

}
